/**
 *
 */
package de.cbf.cam.dsa.person.generator;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import de.cbf.cam.dsa.person.entities.PersonBaseDSA;
import de.cbf.cam.dsa.person.entities.PersonSpecialsDSA;
import de.cbf.cam.dsa.person.extension.interfaces.AbstractNamedGenerator;
import de.cbf.cam.dsa.person.extension.interfaces.IPersonSpecialsGenerator;
import de.cbf.cam.dsa.rcp.model.entities.CultureDSA;
import de.cbf.cam.dsa.rcp.model.entities.PerkDSA;
import de.cbf.cam.dsa.rcp.model.entities.ProfessionDSA;
import de.cbf.cam.dsa.rcp.model.entities.RCPPerked;
import de.cbf.cam.dsa.rcp.model.entities.RaceDSA;
import de.cbf.util.number_generator.RandomNumberGenerator;
import de.cbf.util.uuidheader.entities.EntityWeighted;
import de.cbf.util.uuidheader.util.EntityWeightedList;

/**
 * @author salter
 *
 */
public class PersonSpecialsGenerator extends AbstractNamedGenerator implements IPersonSpecialsGenerator {

	protected RandomNumberGenerator rnd;

	protected EntityWeightedList requiredPerks;
	protected EntityWeightedList optionalPerks;
	/**
	 *
	 */
	public PersonSpecialsGenerator() {
		setName("Person Specials Generator");
		requiredPerks = new EntityWeightedList();
		optionalPerks = new EntityWeightedList();
		rnd = RandomNumberGenerator.getInstance();
	}

	@Override
	public void generatePersonSpecials(PersonBaseDSA person,Map<String, Object> properties,
			RaceDSA race, CultureDSA culture,ProfessionDSA profession) {
		PersonSpecialsDSA result = null;
		if(person.getSpecials() == null){
			result = new PersonSpecialsDSA();
		}else{
			result = person.getSpecials();
		}

		//find all perks from rcp, split by required and optional
		splitPerks(race);
		splitPerks(culture);
		splitPerks(profession);
		//add required perks to person
		List<PerkDSA> personPerks = new ArrayList<PerkDSA>();
		for (EntityWeighted entity : requiredPerks) {
			if (entity instanceof PerkDSA) {
				PerkDSA perkDSA = (PerkDSA) entity;
				personPerks.add(perkDSA);
			}
		}
		//find number of optional perks from properties
		Integer min = 0;
		Integer max = 0;
		Object object;
		object = properties.get(IPersonSpecialsGenerator.OPTIONAL_PERKS_MIN);
		if (object instanceof Integer) {
			min = (Integer) object;
		}
		object = properties.get(IPersonSpecialsGenerator.OPTIONAL_PERKS_MAX);
		if (object instanceof Integer) {
			max = (Integer) object;
		}
		int numberOptionalPerks = rnd.findRandomBetweenMinMax(min, max);
		//choose number of optional perks(maybe from property
		for (int i = 0; i < numberOptionalPerks; i++) {
			EntityWeighted entity = optionalPerks.chooseEntityByWeight();
			if (entity instanceof PerkDSA) {
				PerkDSA perk = (PerkDSA) entity;
				if( ! personPerks.contains(perk)){//do not add doubles
					personPerks.add(perk);
				}
			}
		}
		//add perks to person specials
		result.setPerks(personPerks);

		person.setSpecials(result);

	}

	protected void splitPerks(RCPPerked perked) {
		for (PerkDSA perk : perked.getWeightedPerks()) {
			if(perk.getRequired()){
				if(! requiredPerks.contains(perk)){
					requiredPerks.add(perk);
				}
			}else{
				if( ! optionalPerks.contains(perk)){
					optionalPerks.add(perk);
				}
			}
		}

	}


}
